import { useGlobalStore } from '@/store/global'
import './cometd-all.min.js'
import { v4 as uuidv4 } from 'uuid'
import Logger from '@/plugins/log'
import { IPage, useMccStore } from '../store'
import { Environment } from '@/utils'
import { IMessage, distribute, preHandle } from '../cometd-message'
/**由于右侧展开即会请求接口，固可根据右侧当前所在页来选择性处理消息 */
const MESSAGE_HANDLE: {
	[K in IPage]?: { [key: string]: 1 }
} = {
	mcc_main: {
		mcc_mt: 1,
		// mcc_mt_add: 1,
		mcc_mt_del: 1,
		mcc_audience: 1,
		mcc_audience_del: 1,
		mcc_smcu_add: 1,
		mcc_smcu_remove: 1,
		mcc_sub_smcu_mt: 1,
		mcc_sub_smcu_mt_del: 1,
		mcc_conf_release: 1,
		mcc_conf_detail: 1,
		mcc_conf_password: 1,
		mcc_meeting_simpleinfo: 1,
		mcc_meeting_viplist: 1,
		mcc_meeting_voiceInspire: 1,
		mcc_meeting_forcebrd: 1,
		mcc_message_popup: 1,
		mcc_meeting_mt_apply: 1,
		mcc_meeting_sysmsg: 1,
		mcc_monitor_start: 1,
		mcc_monitor_fail: 1,
		mcc_monitor_stop: 1,
		mcc_page_refresh: 1,
		mcc_dcs_mt: 1,
		mcc_dcs_conf_status: 1,
		live_conf: 1, //会议直播状态改变
		live_conf_mt_add: 1,
		live_conf_mt_del: 1,
		mcc_mt_kis_devices: 1,
		//状态需要
		mcc_meeting_vmp: 1,
		mcc_meeting_mtvmp: 1,
		//会议放像
		mcc_message_play_status: 1,
		//todo 视情况下面几个可选择性处理
		mcc_meeting_poll: 1,
		mcc_meeting_uppoll: 1,
		mcc_meeting_selectview: 1,
		mcc_meeting_speakerqueue: 1,
	},
	tvwall: {
		mcc_meeting_tvwall: 1,
		mcc_meeting_tvwall_batchpoll: 1,
		mcc_meeting_volume: 1,
		mcc_hdu_fail_msg: 1,
	},
	rollcall: {
		mcc_meeting_rollcall: 1,
		mcc_meeting_rollcall_result: 1,
		mcc_mt_camera_pos_info: 1,
	},
	mt_select: { mcc_meeting_selectview: 1 },
	meeting_poll: { mcc_meeting_poll: 1 },
	chairman_poll: { mcc_meeting_poll: 1 },
	upload: { mcc_meeting_uppoll: 1 },
	meeting_video: { mcc_message_play_status: 1 }, //会议放像
	video_live: { mcc_message_recordrec_status: 1 }, //会议录像
	mt_record: { mcc_message_recordrec_status: 1 }, //终端录像
	mix: { mcc_meeting_mix: 1 },
	mt_camera: { mcc_mt_camera_pos_info: 1, mcc_mt_video_src_info: 1, mcc_mt_cur_video_src_info: 1 },
	mt_info: { mcc_message_mt_detail_info: 1 },
}
class MessageHandle {
	/** 是否开始处理消息 */
	startHandleMsg = false
	/** 处理消息时间间隔 */
	timeInterval = 200
	/** 单次轮询最大消息处理条数 */
	maxHandleCount = 50
	/** 消息队列 */
	task: IMessage[] = []
	/**
	 * 消息处理入口
	 */
	onMessage(message: IMessage) {
		const flag = this.preTreatment(message)
		if (flag === 'handled') return
		this.task.push(message)
	}
	/**消息预处理 */
	preTreatment(message: IMessage) {
		//当前智能混音正在进行，假如来的消息是停止混音，则立即清空消息队列里关于智能混音的全部推送消息，将消息提至最前处理
		if (message.mcc_message_type === 'mcc_meeting_mix') {
			if (message.data?.state === 0) {
				let mixMode = useMccStore.getState().mixMode
				if (mixMode === 1) {
					this.task = this.task.filter((x) => x.mcc_message_type !== 'mcc_meeting_mix')
					this.task.unshift(message)
					return 'handled'
				}
			}
		}
		return 'continue'
	}
	/**开始消息处理 */
	start() {
		if (Environment.isIE) {
			const x = () => {
				this.handleTask()
				setTimeout(() => x(), this.timeInterval)
			}
			x()
		} else {
			const blob = new Blob([
				`
                function x() {
                    postMessage('');
                    setTimeout(function(){
                        x()
                    }, ${this.timeInterval});
                }
                x()
            `,
			])
			const url = window.URL.createObjectURL(blob)
			const worker = new Worker(url)
			worker.onmessage = () => {
				this.handleTask()
			}
		}
	}
	handleTask() {
		if (this.task.length > 0 && this.startHandleMsg) {
			let m: IMessage[] = []
			for (let i = 0; i < this.maxHandleCount && this.task.length > 0; i++) {
				//取得一部分消息进行处理
				m.push(this.task.shift()!)
			}
			for (let i = 0; i < m.length; i++) {
				const message = m[i]
				if (message && message.meeting_moid === useMccStore.getState().mccInfo.meetingMoid) {
					const mcc_message_type = message.mcc_message_type
					try {
						//预处理
						preHandle(message)
						const curPage = useMccStore.getState().curPage
						if (MESSAGE_HANDLE[curPage]?.[mcc_message_type]) {
							// console.log(`==============开始处理 ${mcc_message_type} =============`)
							console.log(message)
							distribute(message)
						} else if (MESSAGE_HANDLE.mcc_main![mcc_message_type]) {
							// console.log(`==============开始处理 ${mcc_message_type} =============`)
							console.log(message)
							distribute(message)
						} else {
							// console.warn(`${mcc_message_type} {t('未处理')}`)
						}
					} catch (e) {
						console.log(e)
					}
				}
			}
		}
	}
}
export const MessageRun = new MessageHandle()
export function cometdInit(meetingMoid: string) {
	let cometd = new window.org.cometd.CometD()
	if (window.WebSocket) {
		cometd.registerTransport('websocket', new window.org.cometd.WebSocketTransport())
	}
	cometd.registerTransport('long-polling', new window.org.cometd.LongPollingTransport())
	cometd.registerTransport('callback-polling', new window.org.cometd.CallbackPollingTransport())
	const moid = useGlobalStore.getState().user?.moid
	const config = {
		moid,
		uuid: uuidv4(),
		meetingMoid,
		subscribeOption: {
			channel: '/meeting/' + meetingMoid,
			subscribeCallBack: () => {
				//通道订阅成功回调
				MessageRun.start()
			},
			onMessage: (message: any) => {
				// 消息处理
				try {
					if (message == null || !message.data) {
						return true
					}
					// 处理消息
					MessageRun.onMessage(JSON.parse(message.data))
					Logger.add({ info: { data: message.data }, type: `cometd` })
				} catch (e) {
					//消息解析出错
					// console.log(消息解析出错 + e)
					console.log(message)
					Logger.add({ info: { data: message.data }, type: `Error-cometd` })
				}
				return true
			},
		},
		url: `${window.location.protocol}//${window.location.host}/service/cometd`,
	}
	console.time('cometd 耗时：')
	console.time('cometd 耗时handshake:')
	let _subscription: null
	let _disconnecting: null
	let _connected: boolean
	cometd.addListener('/meta/handshake', (message: { successful: boolean }) => {
		console.timeEnd('cometd 耗时handshake:')
		if (message.successful) {
			console.time('cometd 耗时_subscribe：')
			cometd.batch(function () {
				try {
					_subscription = cometd.subscribe(config.subscribeOption.channel, config.subscribeOption.onMessage)
					console.log('cometd 订阅执行成功')
				} catch (e) {
					console.log('cometd 订阅执行失败')
				}
			})
			console.log('cometd 握手成功 ')
		} else {
			console.log('cometd 握手失败 ')
			cometd.websocketEnabled = false
		}
	})
	cometd.addListener('/meta/connect', (message: { successful: boolean }) => {
		if (_disconnecting) {
			_connected = false
		} else {
			var wasConnected = _connected
			_connected = message.successful === true
			if (!wasConnected && _connected) {
				//_connectionEstablished
				cometd.publish('/service/members', {
					user: config.moid,
					uuid: config.uuid,
					meetingId: config.meetingMoid,
				})
			} else if (wasConnected && !_connected) {
				//_connectionBroken
			}
		}
	})
	cometd.addListener('/meta/subscribe', function (message: { successful: boolean; subscription: string }) {
		if (message.successful) {
			//订阅成功
			if (message.subscription === config.subscribeOption.channel) {
				//会控中的消息
				console.timeEnd('cometd 耗时_subscribe：')
				console.timeEnd('cometd 耗时：')
				config.subscribeOption.subscribeCallBack()
			}
		}
	})
	window.addEventListener('unload', (event) => {
		cometd.disconnect()
	})
	cometd.websocketEnabled = true
	cometd.configure({
		backoffIncrement: 2000,
		url: config.url,
		logLevel: 'warn',
	})
	cometd.handshake()
	return () => {
		cometd.batch(function () {
			if (_subscription) {
				cometd.unsubscribe(_subscription)
			}
			_subscription = null
		})
		cometd.disconnect()
		_disconnecting = null
	}
}
